package com.ruoyi.system.service.impl;

import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.NcGoods;
import com.ruoyi.system.domain.NcMeterial;
import com.ruoyi.system.domain.NcMeterialForStandard;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.mapper.NcMeterialMapper;
import com.ruoyi.system.service.INcMeterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物资管理 服务实现
 *
 * @author ruoyi
 */
@Service
public class NcMeterialServiceImpl implements INcMeterialService {
    @Autowired
    private NcMeterialMapper meterialMapper;

    /**
     * 查询物资管理数据
     *
     * @param meterial 物资信息
     * @return 物资信息集合
     */
    @Override
    public List<NcMeterial> selectMeterialList(NcMeterial meterial) {
        return meterialMapper.selectMeterialList(meterial);
    }

    @Override
    public List<NcMeterialForStandard> selectMeterialListHasParent(NcMeterialForStandard meterial) {
        return meterialMapper.selectMeterialListHasParent(meterial);
    }

    /**
     * 查询物资管理树
     *
     * @param meterial 物资信息
     * @return 所有物资信息
     */
    @Override
    public List<Ztree> selectMeterialTree(NcMeterial meterial) {
        List<NcMeterial> meterialList = meterialMapper.selectMeterialList(meterial);
        List<Ztree> ztrees = initZtree(meterialList);
        return ztrees;
    }

    /**
     * 根据角色ID查询物资（数据权限）
     *
     * @param role 角色对象
     * @return 物资列表（数据权限）
     */
    @Override
    public List<Ztree> roleMeterialTreeData(SysRole role) {
        Long roleId = role.getRoleId();
        List<Ztree> ztrees = new ArrayList<Ztree>();
        List<NcMeterial> meterialList = selectMeterialList(new NcMeterial());
        if (StringUtils.isNotNull(roleId)) {
            List<String> roleMeterialList = meterialMapper.selectRoleMeterialTree(roleId);
            ztrees = initZtree(meterialList, roleMeterialList);
        } else {
            ztrees = initZtree(meterialList);
        }
        return ztrees;
    }

    /**
     * 对象转物资树
     *
     * @param meterialList 物资列表
     * @return 树结构列表
     */
    public List<Ztree> initZtree(List<NcMeterial> meterialList) {
        return initZtree(meterialList, null);
    }

    /**
     * 对象转物资树
     *
     * @param meterialList     物资列表
     * @param roleMeterialList 角色已存在菜单列表
     * @return 树结构列表
     */
    public List<Ztree> initZtree(List<NcMeterial> meterialList, List<String> roleMeterialList) {

        List<Ztree> ztrees = new ArrayList<Ztree>();
        boolean isCheck = StringUtils.isNotNull(roleMeterialList);
        for (NcMeterial meterial : meterialList) {

            Ztree ztree = new Ztree();
            ztree.setId(meterial.getMeterialId());
            ztree.setpId(meterial.getParentId());
            ztree.setName(meterial.getMeterialName());
            ztree.setTitle(meterial.getMeterialName());
            if (isCheck) {
                ztree.setChecked(roleMeterialList.contains(meterial.getMeterialId() + meterial.getMeterialName()));
            }
            ztrees.add(ztree);

        }
        return ztrees;
    }

    /**
     * 查询物资人数
     *
     * @param parentId 物资ID
     * @return 结果
     */
    @Override
    public int selectMeterialCount(Long parentId) {
        NcMeterial meterial = new NcMeterial();
        meterial.setParentId(parentId);
        return meterialMapper.selectMeterialCount(meterial);
    }

    /**
     * 查询物资是否存在用户
     *
     * @param meterialId 物资ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkMeterialExistUser(Long meterialId) {
        int result = meterialMapper.checkMeterialExistUser(meterialId);
        return result > 0 ? true : false;
    }

    /**
     * 删除物资管理信息
     *
     * @param meterialId 物资ID
     * @return 结果
     */
    @Override
    public int deleteMeterialById(Long meterialId) {
        return meterialMapper.deleteMeterialById(meterialId);
    }

    /**
     * 新增保存物资信息
     *
     * @param meterial 物资信息
     * @return 结果
     */
    @Override
    public int insertMeterial(NcMeterial meterial) {
        NcMeterial info = meterialMapper.selectMeterialById(meterial.getParentId());
        // 如果父节点不为"正常"状态,则不允许新增子节点
        /*if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
            throw new BusinessException("物资停用，不允许新增");
        }*/
        meterial.setAncestors(info.getAncestors() + "," + meterial.getParentId());
        return meterialMapper.insertMeterial(meterial);
    }

    /**
     * 修改保存物资信息
     *
     * @param meterial 物资信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMeterial(NcMeterial meterial) {
        NcMeterial newParentMeterial = meterialMapper.selectMeterialById(meterial.getParentId());
        NcMeterial oldMeterial = selectMeterialById(meterial.getMeterialId());
        if (StringUtils.isNotNull(newParentMeterial) && StringUtils.isNotNull(oldMeterial)) {
            String newAncestors = newParentMeterial.getAncestors() + "," + newParentMeterial.getMeterialId();
            String oldAncestors = oldMeterial.getAncestors();
            meterial.setAncestors(newAncestors);
            updateMeterialChildren(meterial.getMeterialId(), newAncestors, oldAncestors);
        }
        int result = meterialMapper.updateMeterial(meterial);
        /*if (UserConstants.DEPT_NORMAL.equals(cai.getStatus())) {
            // 如果该物资是启用状态，则启用该物资的所有上级物资
            updateParentCaiStatus(cai);
        }*/
        return result;
    }

    /**
     * 修改该物资的父级物资状态
     *
     * @param meterial 当前物资
     */
    private void updateParentMeterialStatus(NcMeterial meterial) {
        String updateBy = meterial.getUpdateBy();
        meterial = meterialMapper.selectMeterialById(meterial.getMeterialId());
        meterial.setUpdateBy(updateBy);
        meterialMapper.updateMeterialStatus(meterial);
    }

    /**
     * 修改子元素关系
     *
     * @param meterialId        被修改的物资ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateMeterialChildren(Long meterialId, String newAncestors, String oldAncestors) {
        List<NcMeterial> children = meterialMapper.selectChildrenMeterialById(meterialId);
        for (NcMeterial child : children) {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            meterialMapper.updateMeterialChildren(children);
        }
    }

    /**
     * 根据物资ID查询信息
     *
     * @param meterialId 物资ID
     * @return 物资信息
     */
    @Override
    public NcMeterial selectMeterialById(Long meterialId) {
        return meterialMapper.selectMeterialById(meterialId);
    }

    /**
     * 校验物资名称是否唯一
     *
     * @param meterial 物资信息
     * @return 结果
     */
    @Override
    public String checkMeterialNameUnique(NcMeterial meterial) {
        Long caiId = StringUtils.isNull(meterial.getMeterialId()) ? -1L : meterial.getMeterialId();
        NcMeterial info = meterialMapper.checkMeterialNameUnique(meterial.getMeterialName(), meterial.getParentId());
        if (StringUtils.isNotNull(info) && info.getMeterialId().longValue() != caiId.longValue()) {
            return UserConstants.DEPT_NAME_NOT_UNIQUE;
        }
        return UserConstants.DEPT_NAME_UNIQUE;
    }

    @Override
    public List<NcMeterial> selectMeterialIdByName(String meterialName) {
        return meterialMapper.selectMeterialIdByName(meterialName);
    }

    @Override
    public Object frontSelectNcGoodsMeter(String startTime, String endTime) {
        List<NcMeterial> list =  meterialMapper.frontSelectNcGoodsMeter(startTime,endTime);
        List<NcMeterial> root = list.stream().filter(t->t.getParentId() == 0).collect(Collectors.toList());
        List<NcMeterial> sortList = list.stream().filter(t->t.getParentId() == root.get(0).getMeterialId()).collect(Collectors.toList());
        List<Integer> sumList = new ArrayList<>(sortList.size());
        for(int i = 0 ; i < sortList.size(); i++){
            Long meterId = sortList.get(i).getMeterialId();
            List<NcMeterial> groupList = list.stream().filter(t->t.getParentId()== meterId  && StringUtils.isNotEmpty(t.getLogCreateTime())).collect(Collectors.toList());
            int total = groupList.stream().collect(Collectors.summingInt(NcMeterial::getAmount));
            sumList.add(total);
        }
        Map<String,List> result = new HashMap<>();
        result.put("sortList",sortList);
        result.put("sumList",sumList);
        return result;
    }

    @Override
    public void SelectNcGoodsMeter(ModelMap mmap, NcGoods ncGoods) {
        String beginTime = (String) ncGoods.getParams().get("beginTime");
        String endTime = (String) ncGoods.getParams().get("endTime");
        List<NcMeterial> firstSortList = meterialMapper.selectMeterialFirstSort(0);
        List<Integer> valList = new ArrayList<>();
        for(NcMeterial me : firstSortList){
            Map map = new HashMap();
            map.put("startTime",beginTime);
            map.put("endTime",endTime);
            map.put("meterailId",me.getMeterialId());
            Integer total = meterialMapper.countGoodsByMeterID(map);
            valList.add(total == null ? 0 : total);
        }
        List<String> keysList = new ArrayList<>();
        List<Map> list = new ArrayList<>();
        for(int i = 0 ; i < firstSortList.size(); i++){
            NcMeterial nc = firstSortList.get(i);
            keysList.add(nc.getMeterialName());
            Map map = new HashMap<>();
            map.put("type",nc.getMeterialId());
            map.put("key",nc.getMeterialName());
            map.put("val",valList.get(i));
            map.put("class",(i + 1) + " " + (i == 0 ? "" : ""));
            list.add(map);
        }
        Map map = getSelectdTotalGoods(valList,true);
        list.add(0,map);
        mmap.put("key",keysList );
        mmap.put("val",valList);
        mmap.put("list",list);
    }

    private Map getSelectdTotalGoods(List<Integer> valList,Boolean selectd) {
        Integer total = 0;
        Map map = new HashMap();
        map.put("type","all");
        map.put("key","总计数量");
        for(Integer i : valList){
           total = total+i;
        }
        map.put("val",total);
        map.put("class",selectd == true ? "1 active" : "1 ");
        return map;
    }


    @Override
    public List<NcMeterial> selectMeterialFirstSort(int i) {
        return meterialMapper.selectMeterialFirstSort(i);

    }

    @Override
    public List<NcMeterial> selectMeterialParentId(long parentId) {
        NcMeterial meterial=new NcMeterial();
        meterial.setParentId(parentId);
        return meterialMapper.selectMeterialList(meterial);
    }


}
